#ifndef LONGKEY_COMMON_REACTOR_H_
#define LONGKEY_COMMON_REACTOR_H_

#include <vector>
#include <Windows.h>
#include "basictypes.h"

class EventHandler;

class Reactor
{
public:
	Reactor();
	~Reactor();

	// Starts demultiplexing and dispatching events.
	HRESULT HandleEvents();

	// Registers an event handler for a handle. The reactor does not own the
	// handle. Registering the same handle twice results in undefined behavior.
	// The flags parameter can be one of the WT* thread pool values or 0 for
	// a reasonable default.
	HRESULT RegisterHandle(HANDLE handle, 
		EventHandler* event_handler, 
		UINT32 flags);

	// Registers the handle again. This method can be called from the callback.
	HRESULT RegisterHandle(HANDLE handle);

	// Unregisters the handle. The method blocks and waits for any callback to
	// complete if an event dispatching is in progress.
	HRESULT UnregisterHandler(HANDLE handle);

private:
	struct RegistrationState
	{
		RegistrationState() :
			reactor(NULL),
			event_handler(NULL),
			handle(NULL),
			wait_handle(NULL),
			flags(0) {}

		Reactor*		reactor;
		EventHandler*	event_handler;
		HANDLE			handle;
		HANDLE			wait_handle;
		uint32			flags;
	};

	static void __stdcall Callback(void* param, BOOLEAN timer_or_wait);
	void DoCallback(RegistrationState* registeration_state);

	HRESULT DoRegisterHandle(HANDLE handle);

	// Releases the ownership of registration state corresponding to a handle.
	RegistrationState* ReleaseHandlerState(HANDLE handle);

	CRITICAL_SECTION cs_;
	std::vector<RegistrationState*> handlers_;

	DISALLOW_EVIL_CONSTRUCTORS(Reactor);
};

#endif	// LONGKEY_COMMON_REACTOR_H_